﻿//////////////////////////////////////////////////////////////////////
//                       Class MaxFilter                            //
//         Haalt een Max filter van 3x3 over de InputImage          //
//                                                                  //
//                          Made By:                                //
//                      Hessel Meulenbeld                           //
//                                                                  //
//                          Version:                                //
//                1.0 - Hessel Meulenbeld - 16-03-2012              //
//                                                                  //
//////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Collections;
using THO7AlgorithmBase;

namespace THO7AlgoritmTimerApplication {
    class MaxFilter : VisionAlgorithm {
        public MaxFilter(String name) : base(name) { }
        public override System.Drawing.Bitmap DoAlgorithm(System.Drawing.Bitmap sourceImage) {
            int filter_groote = 3;
            Bitmap returnImage = new Bitmap(sourceImage);
            //lock de bitmap data.
            Rectangle rect = new Rectangle(0, 0, returnImage.Width, returnImage.Height);
            BitmapData myBmpData = returnImage.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr = myBmpData.Scan0;
            int numBytes = returnImage.Width * returnImage.Height * 3;
            byte[] rgbValues = new byte[numBytes];
            byte[] newrgbValues = new byte[numBytes];
            Marshal.Copy(ptr, rgbValues, 0, numBytes);
            //maak de arrays voor de verschillende kleuren aan.
            int[] medianR = new int[filter_groote * filter_groote];
            int[] medianG = new int[filter_groote * filter_groote];
            int[] medianB = new int[filter_groote * filter_groote];
            //loop de image door en pak per pixel alle waardes die binnen de filter_groote vallen.
            int regelGroote = returnImage.Width * 3;
            for (int imagex = (filter_groote / 2); imagex < sourceImage.Width - (filter_groote / 2); imagex++)
            {
                for (int imagey = (filter_groote / 2); imagey < sourceImage.Height - (filter_groote / 2); imagey++)
                {
                    int counter = 0;
                    for (int y = imagey - (filter_groote / 2); y <= imagey + (filter_groote / 2); y++)
                    {
                        for (int x = imagex - (filter_groote / 2); x <= imagex + (filter_groote / 2); x++)
                        {
                            medianR[counter] = (int)rgbValues[x * 3 + (y * regelGroote)];
                            medianG[counter] = (int)rgbValues[x * 3 + (y * regelGroote) + 1];
                            medianB[counter] = (int)rgbValues[x * 3 + (y * regelGroote) + 2];

                            counter++;
                        }
                    }
                    //pak de grootste waardes uit de arrays en zet ze op het midden van het filter.
                    newrgbValues[imagex * 3 + (imagey * regelGroote)] = (byte)medianR.Max();
                    newrgbValues[imagex * 3 + (imagey * regelGroote) + 1] = (byte)medianG.Max();
                    newrgbValues[imagex * 3 + (imagey * regelGroote) + 2] = (byte)medianB.Max();

                }
            }
            rgbValues = newrgbValues;
            //unlock de bitmap
            Marshal.Copy(rgbValues, 0, ptr, numBytes);
            returnImage.UnlockBits(myBmpData);
            return returnImage;
        }
    }
}
